<?php
namespace app\lucky\controller;
use \app\check\controller\Check;
use \think\Db;
use \think\Cache;

// 女神幸运星🌟
class oldPlanet extends Check
{
    protected $prize_total_num = 0;// 今日抽奖总次数
    private $every_day_max = 17500;// 每日抽奖总上限 50000 305   25000  17500
    private $user_today_max = 3;// 用户每日抽取上限
    private $prize_max = 3500;// 多少人内必中 10000 61   5000   3500
    private $prize_other_tips_refresh = false;

    public function _initialize()
    {
        parent::_initialize();

        $this->lucky_init();// 抽奖初始化
    }

    /**
     * 领取幸运星
     * 奖项存入redis
     * @param int uid  用户id
     * @redis prize 所有奖项
     * @redis prize_date 抽奖日期
     * @redis prize_total_num 今日抽奖总次数
     * @redis prize_today_surplus 今日剩余奖项
     * @redis prize_count_user_$uid 当前用户今日抽奖次数  总次数3次
     * @redis prize_user_$uid 当前用户抽中的奖项
     * @return json
     */
    public function get()
    {
        $uid = $this->user['id'];

        $time = time();

        try
        {
            // 当前用户今天中奖数据
            $user_lucky = Db::table('wechat_backup_07_18_14_43_00.app_user_lucky_num')
                ->field('*')->where('uid', $uid)
                ->whereTime('create_time', 'today')
                ->order('id DESC')
                ->select();

            // 获取今日抽奖次数
            $total = Db::table('wechat_backup_07_18_14_43_00.app_user_lucky_num')->whereTime('create_time', 'today')->count();
        }
        catch (\Exception $e)
        {
            // 错误信息写入日志
            \think\Log::write($e->getMessage(),'error',true);

            return show(config('code.error'),'请稍后重试');
        }
        $prize_count_user = $this->user_today_max;
        // 判断本日3次机会是否已经领取完 或者 距离今天的上一次领取 不到4小时
        if(!empty($user_lucky))
        {
            $prize_count_user -= count($user_lucky);

            if($prize_count_user <= 0)
            {
//                return show(config('code.error'),'今日机会已用完，明天再来吧！');
                return show(11301,'今日机会已用完，明天再来吧！');
            }
            if($user_lucky[0]['create_time'] + 14400 > $time)
            {
//                return show(config('code.error'),'稍后再来领取！');
                return show(11305,'稍后再来领取！');
            }
        }

        $prize_count_user--;

        // 获取今日能抽取的奖项
        $prize_today_surplus = Cache::get('prize_today_surplus');

        $total++;
        // 判断抽奖总次数是否已达上限
        if($total > $this->every_day_max)
        {
//            return show(config('code.error'),'今日奖励已发完，明日再来领取！');
            return show(11301,'今日奖励已发完，明日再来领取！');
        }

        $key_or = $total / $this->prize_max;
        if($key_or <= 1) $key = 0;// 含10000   2000
        elseif($key_or <= 2) $key = 1;// 含20000 4000
        elseif($key_or <= 3) $key = 2;// 含30000 6000
        elseif($key_or <= 4) $key = 3;// 含40000 8000
        else $key = 4;// 含50000 10000

        // 当前阶段奖品剩余总数
        $key_count = count($prize_today_surplus[$key]);

        $l = mt_rand(0,$key_count-1);
        // 当前中奖
        $user_get_prize = $prize_today_surplus[$key][$l];
        // 获取所有幸运星词条
        $all_tips = Cache::get('prize_other_tips');

        // 词条id
        $tips_key = mt_rand(0,count($all_tips[$user_get_prize['planet_num']]) - 1);
        // 获取词条
        $tip = $this->get_tips($user_get_prize['prize'],$user_get_prize['planet_num'],$tips_key);

        $tipid = isset($all_tips[$user_get_prize['planet_num']]) ? $all_tips[$user_get_prize['planet_num']][$tips_key]['id'] : null;

        $status = substr($user_get_prize['planet_num'],0,2) == '00' ? 1 : 0;
        // 0未中奖   1未提问   2待回答   3已回复   4已过期  5已兑换
        $prize_insert = [
            'uid'=>$uid,
            'prize'=>$user_get_prize['prize'],
            'planet_num'=>$user_get_prize['planet_num'],
            'create_time'=>$time,
            'tipsid'=>$tipid,
            'status'=>$status
        ];
        // 已中奖项存入数据库
        $id = Db::table('app_user_lucky_num')->insertGetId($prize_insert);

        unset($prize_today_surplus[$key][$l]);

        $prize_today_surplus[$key] = array_values($prize_today_surplus[$key]);

        Cache::set('prize_today_surplus',$prize_today_surplus);// 今日剩余奖项存入

        $data = [
            'status'=>$status,// 中奖状态
            'tip'=>$tip,// 提示语
            'get_time'=>$time,// 领取时间
            'times'=>$prize_count_user,// 剩余次数
            'pid'=>$id// 领取id
        ];

        return show(config('code.success'),'领取成功',$data);
    }

    /**
     * 获取今日幸运中奖名单
     * 获取用户上次抽奖的时间
     */
    public function index()
    {
        $uid = $this->user['id'];

        try
        {
            // 获取今日中奖用户
            $prize_today = Db::table('wechat_backup_07_18_14_43_00.app_user_lucky_num')
                ->alias('uln')
                ->field('uln.id pid,uln.uid,uln.prize,u.nickname,u.avatar,uln.status')
                ->where('uln.status', 'in','1,2,3,4')
                ->join('wechat_backup_07_18_14_43_00.app_user u','uln.uid=u.id','LEFT')
                ->whereTime('uln.create_time', 'today')
                ->order('uln.id DESC')
                ->select();

            $user_times = Db::table('wechat_backup_07_18_14_43_00.app_user_lucky_num')->field('create_time')->where('uid',$uid)->whereTime('create_time','today')->select();
        }
        catch (\Exception $e)
        {
            // 错误信息写入日志
            \think\Log::write($e->getMessage(),'error',true);

            return show(config('code.error'),'请稍后重试');
        }
        $times = $this->user_today_max;

        $time = null;

        if(!empty($user_times))
        {
            $times -= count($user_times);

            $time = end($user_times)['create_time'];
        }

        $data = [
            'list'=>[],
            'times'=>$times,
            'last_time'=>$time
        ];

        if(!empty($prize_today))
        {
            // 查询用户是否为自己中奖
            foreach ($prize_today as $p)
            {
                $p['isself'] = 0;

                if($p['uid'] == $uid)
                {
                    $p['nickname'] = '你';

                    $p['isself'] = 1;
                }
                if(!$p['nickname']) $p['nickname'] = '匿名用户';

                $data['list'][] = $p;
            }
        }
        return show(config('code.success'),'加载成功',$data);
    }

    /**
     * 我的幸运星
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function get_my_lucky()
    {
        $uid = $this->user['id'];
        // 旧版接口 数据未进行分页处理
        if(input('param.access_token/s',''))
        {
//            $data = $this->redis->get('prize_user_'.$uid);
//            $data = Cache::get('prize_user_'.$uid);
            $data = [];
            $new_arr = [];

            if(!$data)
            {
                $data_list = Db::table('wechat_backup_07_18_14_43_00.app_user_lucky_num')
                    ->alias('uln')
                    ->field('uln.id,uln.prize,uln.planet_num,uln.create_time,uln.status,uln.tipsid,question,answer')
                    ->join('wechat_backup_07_18_14_43_00.app_question_answer qa','uln.id=qa.lid','LEFT')
                    ->where("uln.uid=$uid")
                    ->order('uln.id DESC')
                    ->select();

                if(!empty($data_list))
                {
                    foreach ($data_list as $k => $d)
                    {
                        $status = $d['status'];
                        // 是否为中奖的 并且未提问
                        if(substr($d['planet_num'],0,2) == '00' && $status == 1)
                        {
                            // 判断是否已过期
                            if(time() - (int)($d['create_time']) > 3600*24) $status = 4;
                        }
//                        $tips_key = mt_rand(0,count($this->redis->get('prize_other_tips')[$d['planet_num']]) - 1);
                        $tips_key = mt_rand(0,count(Cache::get('prize_other_tips')[$d['planet_num']]) - 1);
                        $tip = $this->get_tips($d['prize'],$d['planet_num'],$tips_key);

                        $data[] = [
                            'id'=>(int)($d['id']),
                            'prize'=>$d['prize'],
                            'planet_num'=>$d['planet_num'],
                            'create_time'=>$d['create_time'],
                            'status'=>$status,
                            'tip'=>$tip,
                            'question'=>isset($d['question']) ? $d['question'] : null,
                            'answer'=>isset($d['answer']) ? $d['answer'] : null,
                        ];
                    }
                }
            }
            else
            {
                foreach ($data as $k => $d)
                {
                    $status = $d['status'];
                    // 是否为中奖的
                    if(substr($d['planet_num'],0,2) == '00' && $status == 1)
                    {
                        // 判断是否已过期
                        if(time() - (int)($d['time']) > 3600*24) $status = 4;
                    }
                    $new_arr[] = [
                        'id'=>$k,
                        'prize'=>$d['prize'],
                        'planet_num'=>$d['planet_num'],
                        'create_time'=>$d['time'],
                        'status'=>$status,
                        'tip'=>$d['tip'],
                        'question'=>isset($d['question']) ? $d['question'] : null,
                        'answer'=>isset($d['answer']) ? $d['answer'] : null,
                    ];
                }
                $data = array_reverse($new_arr);
            }
            if ($data || !empty($data))
            {
                return show(config('code.success'),'加载成功',$data);
//                return json(['code'=>200,'data'=>$data,'msg'=>'Success.']);
            }
            else
            {
//                return show(config('code.success'),'您还没有领取过幸运星哦，快去领取吧~');
                return json(['code'=>200,'data'=>[],'msg'=>'您还没有领取过幸运星哦，快去领取吧~']);
            }
        }
        else
        {
            $new_arr = [];

            $data_list = Db::table('app_user_lucky_num')
                ->alias('uln')
                ->field('uln.id,uln.prize,uln.planet_num,uln.create_time,uln.status,lt.text,question,answer')
                ->join('wechat_backup_07_18_14_43_00.app_question_answer qa','uln.id=qa.lid','LEFT')
                ->join('wechat_backup_07_18_14_43_00.app_lucky_tips lt','uln.tipsid=lt.id','INNER')
                ->where("uln.uid=$uid")
                ->order('uln.id DESC')
                ->paginate(10,false,['query'=>request()->param()])
                ->toArray();
            $data = $data_list['data'];

            if(!empty($data))
            {
                foreach ($data as $k => $d)
                {
                    $status = $d['status'];
                    // 是否为中奖的 并且未提问
                    if(substr($d['planet_num'],0,2) == '00' && $status == 1)
                    {
                        // 判断是否已过期
                        if(time() - (int)($d['create_time']) > 3600*24) $status = 4;
                    }
                    if(substr($d['planet_num'],0,2) != '00')
                        $d['text'] = "你领到一颗{$d['prize']}，".$d['text'];


                    $new_arr[] = [
                        'id'=>(int)($d['id']),
                        'prize'=>$d['prize'],
                        'planet_num'=>$d['planet_num'],
                        'create_time'=>$d['create_time'],
                        'status'=>$status,
                        'tip'=>$d['text'],
                        'question'=>isset($d['question']) ? $d['question'] : null,
                        'answer'=>isset($d['answer']) ? $d['answer'] : null,
                    ];
                }
                $data = $new_arr;
            }
            if ($data || !empty($data))
            {
                $data_list['data'] = $data;

//                return json(['code'=>200,'data'=>$data_list,'msg'=>'加载成功']);
                return show(config('code.success'),'加载成功',$data_list);
            }
            else
            {
                return show(config('code.success'),'您还没有领取过幸运星哦，快去领取吧~');
//                return json(['code'=>200,'data'=>[],'msg'=>'您还没有领取过幸运星哦，快去领取吧~']);
            }
        }
    }

    /**
     * 每日抽奖初始化 TODO 一天内出现两次幸运土星 待处理
     */
    public function lucky_init()
    {
        // 当前日期
        $date = date('Ymd',time());

        // 当前redis中的抽奖日期  如：20180406
        $prize_date  = Cache::get('prize_date');
        // 日期不存在 设置为当前时间
        if($prize_date === false)
        {
            Cache::set('prize_date',$date);
            $prize_date = $date;
        }
        // 缓存所有幸运星词条
        if(!Cache::get('prize_other_tips') || $this->prize_other_tips_refresh === true)
        {
            $lucky_tips = Db::table('app_lucky_tips')
                ->field('id,planet_num,text')
                ->where('status=0')
                ->select();

            $tips = [];

            if(!empty($lucky_tips))
            {
                foreach ($lucky_tips as $lt)
                {
                    $tips[$lt['planet_num']][] = ['id'=>$lt['id'],'text'=>$lt['text']];
                }
            }

            Cache::set('prize_other_tips',$tips);
        }

        // 今日剩余奖项redis中不存在时 或者  今天为新的一天，新建并存入redis
        if(Cache::get('prize_today_surplus') === false || $date != $prize_date)
        {
            // 抽奖时间更新
            Cache::set('prize_date',$date);
            // 获取所有奖项
            $prize = Cache::get('prize');

            if(!$prize || empty($prize))
            {
                try
                {
                    $prize = Db::table('app_prize')
                        ->field('id,prize,v,planet_num')
                        ->where('status=0')
                        ->select();
                }
                catch (\Exception $e)
                {
                    // 错误信息写入日志
                    \think\Log::write($e->getMessage(),'error',true);

                    return show(config('code.error'),'请稍后重试');
                }


                Cache::set('prize',$prize);
            }

            $yes_arr = $no_arr1 = $no_arr2 = [];

            foreach ($prize as $key => $val)
            {
                //  非直接中奖项目  该数组
                if($val['v'] == 1 ) $yes_arr[] = $val;// 中奖项目
                elseif($val['v'] == 2) $no_arr1[] = $val;// 木星相关 概率调低项目
                elseif($val['v'] > 2) $no_arr2[] = $val;// 幸运星
                $arr[] = $val;
            }
            $yes_arr = $this->shuffle_assoc($yes_arr);// 打乱顺序

            $prize_today_surplus = [];

            foreach ($yes_arr as $k1 => $v1)
            {
                // 1 = 1
                $prize_today_surplus[$k1][] = $v1;// 先把大奖存入
                // 12*10 = 120
                for($i1 = 1;$i1 <= 10;$i1++)
                {
                    foreach ($no_arr1 as $k2 => $v2)
                        $prize_today_surplus[$k1][] = $v2;
                }
                // 48*208 = 9888
                for($i2=1;$i2<=208;$i2++)
                {
                    if(count($prize_today_surplus[$k1]) >= $this->prize_max) break;

                    foreach($no_arr2 as $k3 => $v3)
                    {
                        $prize_today_surplus[$k1][] = $v3;

                        if(count($prize_today_surplus[$k1]) >= $this->prize_max) break;
                    }
                }
                $prize_today_surplus[$k1] = $this->shuffle_assoc($prize_today_surplus[$k1]);
            }
            Cache::set('prize_today_surplus',$prize_today_surplus);// 今日剩余奖项存入
        }

    }

    /**
     * 去提问
     */
    public function push_question()
    {
        $pid = input('pid/d');// 中奖id

        $uid = $this->user['id'];

        try
        {
            $my_prize = Db::table('app_user_lucky_num')
                ->where("uid=$uid and id=$pid and status=1")
                ->find();
        }
        catch (\Exception $e)
        {
            // 错误信息写入日志
            \think\Log::write($e->getMessage(),'error',true);

            return show(config('code.error'),'请稍后重试');
        }

        if(!$my_prize || empty($my_prize))
        {
            return show(config('code.error'),'幸运星不存在');
        }

        $time = time();

        if($my_prize['create_time'] + 86400 < $time)
        {
            try
            {
                Db::table('app_user_lucky_num')->where(['id' => $pid])->update(['status' => 4]);
            }
            catch (\Exception $e)
            {
                // 错误信息写入日志
                \think\Log::write($e->getMessage(),'error',true);

                return show(config('code.error'),'请稍后重试');
            }
            return show(config('code.error'),'哎呀呀，没有及时提问，已经过期啦！继续抽取幸运星，期待下一次机会吧！');
        }

        $content = htmlspecialchars(input('text'));

        if(mb_strlen($content,'utf8') > 100)
        {
            return show(config('code.error'),'提问字数超出限制');
        }

        $insert_data = [
            'lid'=>$pid,
            'uid'=>$uid,
            'question'=>$content,
            'create_time'=>$time,
            'status'=>0// 0 待回答  1已回答
        ];

        try
        {
            $id = Db::table('app_question_answer')->insertGetId($insert_data);

            Db::table('app_user_lucky_num')->where(['id' => $pid])->update(['status' => 2]);
        }
        catch (\Exception $e)
        {
            // 错误信息写入日志
            \think\Log::write($e->getMessage(),'error',true);

            return show(config('code.error'),'请稍后重试');
        }

        return show(config('code.success'),'提问成功');
    }

    /**
     * 获取中奖提示语
     * @param string $title 如：幸运金星 || 白羊座金星
     * @param null $planet_num 如： NULL || 0103
     * @param int $key
     * @return string 返回中奖的提示
     */
    public function get_tips($title = '',$planet_num = null,$key = 0)
    {
        if(substr($planet_num,0,2) == '00')
            $text = Cache::get('prize_other_tips')[$planet_num][$key]['text'];
        else
            $text = "你领到一颗{$title}，".Cache::get('prize_other_tips')[$planet_num][$key]['text'];

        return $text;
    }

    /**
     * 二维数组打乱顺序
     * @param $list
     * @return array
     */
    public function shuffle_assoc($list)
    {
        if (!is_array($list)) return $list;

        $keys = array_keys($list);

        shuffle($keys);

        $random = array();

        foreach ($keys as $key)
            $random[$key] = $list[$key];// 只打乱第一层key
//        $random[$key] = $this->shuffle_assoc($list[$key]);// 第二层key打乱
        return array_values($random);
    }
}
